package com.tqfframe.website.web.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.codingapi.txlcn.tc.annotation.LcnTransaction;
import com.tqfframe.website.client.UserClient;
import com.tqfframe.website.web.common.Result;
import com.tqfframe.website.web.dao.TestMapper;
import com.tqfframe.website.web.vo.TestDTO;
import com.tqfframe.website.web.entry.TestEntity;
import com.tqfframe.website.web.service.TestService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * Created by Tang-QiFeng on 2020/6/24
 */
@RestController
public class TestController {

    Logger logger = LoggerFactory.getLogger(TestController.class);

    @Autowired
    private UserClient userClient;
    @Autowired
    private TestService testService;
    @Autowired
    private TestMapper testMapper;

    @Value(value = "${tang}")
    private String tang;

    /**
     *  本地
     *  http://localhost:8080/api/website/testhystrix/11111
     *  http://localhost:9001/testhystrix/11111
     *
     *  docker
     *  http://192.168.47.135:8080/api/website/testhystrix/11111
     *  http://192.168.47.135:9001/testhystrix/11111
     *
     * @param name
     * @return
     */
    @GetMapping(value = "/testhystrix/{name}")
    public String testhystrix(@PathVariable(name = "name") String name){
        logger.info(name);
        logger.debug(name);
        logger.error(name);
        logger.info(tang);
        //调用user服务接口
        return  userClient.testhystrix(name);
    }

    /**
     *   http://localhost:9001/addOne/tang9/1
     *
     *  新增数据
     * @return
     */
    @Transactional
    @LcnTransaction
    @GetMapping(value = "/addOne/{username}/{state}")
    public Result<TestEntity> addOne(@PathVariable(name = "username") String username,@PathVariable(name = "state") String state) {
        Result<TestEntity> result = new Result<TestEntity>();
        TestEntity testEntity=new TestEntity();
        testEntity.setUsername(username);
        testEntity.setPassword("123456");
        testEntity.setSex(1);
        int aa = testMapper.insert(testEntity);
        if (aa==0) {
            result.setSuccess(false);
        } else {
            logger.debug("feign调用微服务修改状态，如果那边微服务调用失败，将会进行事务" );
            String results=userClient.updateOrder(state);
            logger.info(results);
            result.setSuccess(true);
        }
        logger.debug("在这里模拟卡顿，查看事务是否成功，事实证明，当前微服务没有插入数据，调用的微服务也没有修改数据！");
//        try {
//            throw new Exception();
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//        try {
//            Thread.sleep(20000);
//        } catch (InterruptedException e) {
//            e.printStackTrace();
//        }
        return result;
    }

    /**
     *       http://localhost:9001/getOne/1
     * @param id
     * @return
     */
    @GetMapping(value = "/getOne/{id}")
    public Result getOne(@PathVariable String id) {
        Result<TestEntity> result = new Result<TestEntity>();
        TestEntity aa = testMapper.selectById(id);
//        TestEntity aa = testService.getById(id);
        if (aa == null) {
            result.error500("未找到对应实体");
        } else {
            result.setResult(aa);
            result.setSuccess(true);
        }
        return result;
    }

    /**
     *      http://localhost:8080/api/website/list/0/10
     *      http://localhost:9001/list/0/10
     * @param pageNum
     * @param pageSize
     * @return
     */
    @RequestMapping(value = "/list/{pageNum}/{pageSize}", method = RequestMethod.GET)
    public Result<IPage<TestDTO>> queryPageList(@PathVariable Integer pageNum, @PathVariable Integer pageSize) {
        Result<IPage<TestDTO>> result = new Result<IPage<TestDTO>>();
        // IPage的convert()方法做包装
        IPage<TestDTO> pageList = testMapper.getPageByName(new Page(pageNum, pageSize), "tang123");
        result.setSuccess(true);
        result.setResult(pageList);
        return result;
    }
//
//    @RequestMapping("/buyShop")
//    public String buyShop(){
//        //对要购买的商品编号进行加锁。
//        String lockKey="product_id_001";
//        Rlock redissonLock=redisson.getLock(lockKey);
//        try {
//            //对第一个线程拿到锁后，其他线程访问该锁都会阻塞着。直到锁释放。
//            redissonLock.lock(10,TimeUnit.SECONDS);
//            int stock=Integer.parseInt(redisTemplate.opsForValue().get("stock"));
//            if(stock>0){
//                int realStock=stock-1;
//                redisTemplate.opsForValue().set("stock",realStock+"");
//                System.out.print("扣减库存成功，剩余库存"+realStock);
//            }else{
//                System.out.print("库存不足！");
//            }
//
//        }finally {
//            redissonLock.unlock();
//        }
//        return "ok";
//    }

//    @RequestMapping("/buyShop")
//    public String buyShop(){
//          //对要购买的商品编号进行加锁。
//        String lockKey="product_id_001";
//        String clientId=UUID.randomUUID().toString();
//        try {
//            //这种方式实现会导致如果当前线程卡顿时间超过10秒，导致锁过期，那么下一个线程访问就会新持有锁，如果接下来线程都执行超过10秒，就都会绕过锁，从而导致数据出现问题。
//            Boolean result=redisTemplate.opsForValue().setIfAbset(lockKey,clientId,10, TimeUnit.SECONDS);
//            if(!result){
//                return "error";
//            }
//            int stock=Integer.parseInt(redisTemplate.opsForValue().get("stock"));
//            if(stock>0){
//                int realStock=stock-1;
//                redisTemplate.opsForValue().set("stock",realStock+"");
//                System.out.print("扣减库存成功，剩余库存"+realStock);
//            }else{
//                System.out.print("库存不足！");
//            }
//
//        }finally {
//            if(clientId.equals(redisTemplate.opsForValue().get(lockKey))){
//                redisTemplate.delete(lockKey);
//            }
//        }
//        return "ok";
//    }





    //redLock实现分布式锁
//    @RequestMapping("/buyShop")
//    public String buyShop(){
//        Config config1 = new Config();
//        config1.useSingleServer().setAddress("redis://192.168.0.1:5378") .setPassword("a123456").setDatabase(0);
//        RedissonClient redissonClient1 = Redisson.create(config1);
//        Config config2 = new Config();
//        config2.useSingleServer().setAddress("redis://192.168.0.1:5379") .setPassword("a123456").setDatabase(0);
//        RedissonClient redissonClient2 = Redisson.create(config2);
//        Config config3 = new Config();
//        config3.useSingleServer().setAddress("redis://192.168.0.1:5380") .setPassword("a123456").setDatabase(0);
//        RedissonClient redissonClient3 = Redisson.create(config3);
//        //对要购买的商品编号进行加锁。
//        String lockKey="product_id_001";
//        RLock lock1 = redissonClient1.getLock(lockKey);
//        RLock lock2 = redissonClient2.getLock(lockKey);
//        RLock lock3 = redissonClient3.getLock(lockKey);
//        // 向3个redis实例尝试加锁
//         RedissonRedLock redLock = new RedissonRedLock(lock1, lock2, lock3);
//         boolean isLock;
//         try {
//             isLock = redLock.tryLock();
////             500ms拿不到锁, 就认为获取锁失败。10000ms即10s是锁失效时间。
//             isLock = redLock.tryLock(500, 10000, TimeUnit.MILLISECONDS);
//             System.out.println("isLock = "+isLock);
//         if (isLock) {
//                 if(stock>0){
//                     int realStock=stock-1;
//                     redisTemplate.opsForValue().set("stock",realStock+"");
//                     System.out.print("扣减库存成功，剩余库存"+realStock);
//                 }else{
//                     System.out.print("库存不足！");
//                 }
//             }
//         } catch (Exception e) {
//
//         } finally {
//            // 无论如何, 最后都要解锁
//             redLock.unlock();
//         }
//        return "ok";
//    }

}
